/**
 * 
 */
package com.beta.restapi.internal.auth;

import com.beta.restapi.internal.Consts;
import com.beta.restapi.internal.annotation.AuthSetting;
import com.beta.restapi.internal.annotation.AuthStrategy;
import org.springframework.http.HttpStatus;
import org.springframework.web.method.HandlerMethod;
import org.springframework.web.servlet.HandlerInterceptor;
import org.springframework.web.servlet.ModelAndView;

import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.util.Objects;

/**
 * @author vector
 *
 */
public class AuthInterceptor implements HandlerInterceptor {

	/**
	 * TODO 现阶段使用临时的token管理，后期由统一授权中心管理认证和授权。
	 */
	private AuthService authService;

	/*
	 * (non-Javadoc)
	 * 
	 * @see org.springframework.web.servlet.HandlerInterceptor#preHandle(javax.
	 * servlet.http.HttpServletRequest, javax.servlet.http.HttpServletResponse,
	 * java.lang.Object)
	 */
	@Override
	public boolean preHandle(HttpServletRequest request, HttpServletResponse response, Object handler)
			throws Exception {
		Object currentUser = authService.getCurrentUser(request);
		if (Objects.nonNull(currentUser)) {
			holdCurrentUser(request, currentUser);
			return true;
		}
		
		AuthSetting authorization = getResourceAuthSetting(request, handler);
		if (authorization != null && authorization.level() == AuthStrategy.ANONYMOUS) {
			return true;
		}
		
		handleNoAuth(request, response, handler);
		return false;
	}

	private void holdCurrentUser(HttpServletRequest request, Object currentUser) {
		request.setAttribute(Consts.RequestAttributeKey.USER_OBJ, currentUser);
		authService.isCourierRequest(request);
	}

	private AuthSetting getResourceAuthSetting(HttpServletRequest request, Object handler) {
		if (handler.getClass().isAssignableFrom(HandlerMethod.class)) {
			AuthSetting authorization = ((HandlerMethod) handler).getMethodAnnotation(AuthSetting.class);
			return authorization;
		} else {
			return null;
		}
	}

	private void handleNoAuth(HttpServletRequest request, HttpServletResponse response, Object handler)
			throws Exception {
		response.sendError(HttpStatus.UNAUTHORIZED.value(), "401 Unauthorized");
	}

	/*
	 * (non-Javadoc)
	 * 
	 * @see org.springframework.web.servlet.HandlerInterceptor#postHandle(javax.
	 * servlet.http.HttpServletRequest, javax.servlet.http.HttpServletResponse,
	 * java.lang.Object, org.springframework.web.servlet.ModelAndView)
	 */
	@Override
	public void postHandle(HttpServletRequest request, HttpServletResponse response, Object handler,
			ModelAndView modelAndView) throws Exception {

	}

	/*
	 * (non-Javadoc)
	 * 
	 * @see
	 * org.springframework.web.servlet.HandlerInterceptor#afterCompletion(javax.
	 * servlet.http.HttpServletRequest, javax.servlet.http.HttpServletResponse,
	 * java.lang.Object, java.lang.Exception)
	 */
	@Override
	public void afterCompletion(HttpServletRequest request, HttpServletResponse response, Object handler, Exception ex)
			throws Exception {
		// TODO Auto-generated method stub

	}

	/**
	 * @return the authService
	 */
	public AuthService getAuthService() {
		return authService;
	}

	/**
	 * @param authService
	 *            the authService to set
	 */
	public void setAuthService(AuthService authService) {
		this.authService = authService;
	}

}
